﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.Text.RegularExpressions;
using AcctrueWMS.Foundation.Common;
using AcctrueWMS.Foundation.Common.Exception;
using AcctrueWMS.Foundation.Data;
using AcctrueWMS.Foundation.Util;
using AcctrueWMS.Foundation.Render;


namespace AcctrueWMS.Foundation.Web
{
    public class WebPage
    {
        TemplateManager tplManager = new TemplateManager();
        DataModelManager modelManager = new DataModelManager();
        public WebPage(IDataModelContext context)
        {
            this.context = context;
        }

        IDataModelContext context;
        public IDataModelContext Context
        {
            get { return context; }
        }

        public void Render(HttpContext httpContext)
        {
            HttpRequest request=httpContext.Request;
            HttpResponse response = httpContext.Response;

            string modelName = request.QueryString["model"];
            string templateName = request.QueryString["temp"];
            ModelTemplate template = tplManager.LoadTemplate(string.Format("{0}\\{1}.htm", Runtime.TemplateFilePath, templateName.Trim()));
            template.RenderType = int.Parse(DataHelper.CheckForNull(request.QueryString["opt"],"0"));
            string condition = string.Empty;
            //如果模板中指定了查询条件，则优先使用
            if (template.Meta.ContainsKey("condition"))
                condition +=CommandExprFactory.Eval(template.Meta["condition"],Context).ToString();

            if (request.QueryString["con"]!=null)
            {
                if(!string.IsNullOrEmpty(condition))
                    condition += " and";
                condition +=CommandExprFactory.Eval(request.QueryString["con"],Context).ToString();
            }
   
            //由搜索条件构成的查询串
            string query =request.QueryString["query"];
            string primary = request.QueryString["primary"];
            if (!string.IsNullOrEmpty(query))
            {
                if (!string.IsNullOrEmpty(condition))
                    condition += " and ";
                condition += query;
            }

            if (!string.IsNullOrEmpty(primary) && primary.IndexOf("*") > -1)
            {
                primary = primary.Replace("*", "&");
            }
            //string orderby = request.QueryString["orderby"];

            int currPage = int.Parse(DataHelper.CheckForNull(request.QueryString["currpage"],"0"));
            //url里的pagesize优先于模型中定义
            int pageSize = int.Parse(request.QueryString["pagesize"]!=null? request.QueryString["pagesize"]
                :(template.Meta.ContainsKey("pagesize")?template.Meta["pagesize"]:"15"));
            //url里的orderby优先模型中定义
            string orderby = request.QueryString["orderby"] != null ? request.QueryString["orderby"]
                : (template.Meta.ContainsKey("orderby") ? template.Meta["orderby"] : null);

            if (string.IsNullOrEmpty(templateName))
            {
                throw new WMSSysException("没有模板文件");
            }
            string html = RenderTemplate(modelName, template, condition, orderby, currPage, pageSize, primary, httpContext);
            response.Clear();
            response.Write(html);
            response.End();
        }
       

       
        public string RenderTemplate(string urlModelName,ModelTemplate template,string cond,string orderby,int pageIndex,int pageSize,string primaryKeys,
            HttpContext httpContext)
        {            
            StringWriter sw = new StringWriter();
            //如果存在模型，则加载模型，并分析。部分页面可以没有对应模型
            if (!string.IsNullOrEmpty(urlModelName))
            {
                DataModel model = Runtime.Context.CurrentModel;
                DataModel resultModel=null;
              //  context.RenderMode = template.RenderType;
                switch (template.RenderType)
                {
                    //列表
                    case 0:
                        resultModel = model.Select(cond, orderby, pageIndex * pageSize + 1, pageIndex * pageSize + pageSize);
                        break;
                    //新建
                    case 1:
                         DataModel modelRow = model.NewRow();
                        ///为生成流水号的列生成流水号
                        foreach (DataModelColumn column in modelRow.Columns)
                        {
                            if (column.SequenceNoGenType.Length != 0)
                            {
                                modelRow[column.Name].Value = column.GenerateSequenceNo();
                            }
                        }
                        model.Rows.Add(modelRow);
                        ///如果有兄弟Model,则增加一行
                        foreach (DataModel brotherModel in model.Brothers)
                        {
                            if (brotherModel.Rows.Count == 0)
                            {
                                DataModel brotherRow = brotherModel.NewRow();
                                brotherModel.Rows.Add(brotherRow);
                            }
                        }
                        resultModel = model;
                        break;
                    //修改
                    case 2:
                    case 3:
                        //存在查询条件和主键时
                        if(!string.IsNullOrEmpty(cond)&&!string.IsNullOrEmpty(primaryKeys))
                            cond=cond+" and "+Context.GetQueryCondition(model.Name, primaryKeys,true);
                        else if(!string.IsNullOrEmpty(primaryKeys))
                            cond=Context.GetQueryCondition(model.Name, primaryKeys,false);

                        resultModel = model.Select(cond);
                        break;
                    default:
                        resultModel = model.Select(cond, orderby, pageIndex * pageSize + 1, pageIndex * pageSize + pageSize);
                        break;
                }
                //如果url里定义了load等事件，则覆盖模型中定义事件
                string before = httpContext.Request.QueryString["beforeLoad"];
                string load = httpContext.Request.QueryString["load"];
                string after = httpContext.Request.QueryString["afterload"];

                object result=null;
                string eventExpr = null;
                //触发BeforeLoad事件
                if(!string.IsNullOrEmpty(before))
                    eventExpr=before;
                else
                    eventExpr = modelManager.FindEventHandler(resultModel, DataModelEventNameKeys.BeforeLoad);
                if(!string.IsNullOrEmpty(eventExpr))
                {
                    result = modelManager.ProcessEventExpr(resultModel, eventExpr, context.RenderMode);
                    if (result is bool && !(bool)result)
                        return string.Empty;
                    //如果返回值是DataModel，则使用处理过的Model替换现有的
                    resultModel = (result is DataModel) ? (result as DataModel) : resultModel;
                }

                if (!string.IsNullOrEmpty(load))
                    eventExpr = load;
                else
                    eventExpr = modelManager.FindEventHandler(resultModel, DataModelEventNameKeys.Load);
                if (!string.IsNullOrEmpty(eventExpr))
                {
                    result = modelManager.ProcessEventExpr(resultModel, eventExpr, context.RenderMode);
                    if (result is bool && !(bool)result)
                        return string.Empty;
                    resultModel = (result is DataModel) ? (result as DataModel) : resultModel;
                }
                //Load事件后即执行渲染方法
                context.Render.Render(resultModel, template, sw);

                if (!string.IsNullOrEmpty(after))
                    eventExpr = after;
                else
                    eventExpr = modelManager.FindEventHandler(resultModel, DataModelEventNameKeys.AfterLoad);
                if (!string.IsNullOrEmpty(eventExpr))
                {
                    result = modelManager.ProcessEventExpr(resultModel, eventExpr, context.RenderMode);
                    if (result is bool && !(bool)result)
                        return string.Empty;
                    resultModel = (result is DataModel) ? (result as DataModel) : resultModel;
                }
            }
            else
            {
                context.Render.Render(template.InnerText, sw);
            }
            return sw.ToString();
        }       
    }
}
